﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using NGinnBPM.Lib.Data;
using NGinnBPM.Lib.Util;
using Newtonsoft.Json;

namespace NGinnBPM.Lib.Operations.ExternalServices
{
    /// <summary>
    /// Create a task instance in external application.
    /// Handler should reply with WorkItemCreated
    /// </summary>
    [Serializable]
    [DataContract]
    public class CreateWorkItem 
    {
        [DataMember]
        public string CorrelationId { get; set; }
        /// <summary>Task instance id used for identifying a task instance, unique</summary>
        [DataMember]
        public string InstanceId { get; set; }
        /// <summary>Process instance id</summary>
        [DataMember]
        public string ProcessInstanceId { get; set; }
        ///task identifier in process definition
        [DataMember]
        public DateTime ProcessStartDate { get; set; }
        [DataMember]
        public string TaskId { get; set; }
        /// <summary>Process definition ID</summary>
        [DataMember]
        public string ProcessDefinitionId { get; set; }
        ///<summary>List of correlationIds of work items mutually exclusive with this.</summary>
        [DataMember]
        public string SharedId { get; set; }
        /// <summary>Work item title - as it will appear on TODO list</summary>
        [DataMember]
        public string Title { get; set; }
        /// <summary>Work item description (body) in plain text - non mandatory</summary>
        [DataMember]
        public string Description { get; set; }
        /// <summary>Task description in HTML</summary>
        [DataMember]
        public string DescriptionHtml { get; set; } 
        /// <summary></summary>
        [DataMember]
        public string AssigneeId { get; set; }
        /// <summary>Query used to calculate task assignee, or null.</summary>
        public string AssigneeQuery { get; set; }
        /// <summary></summary>
        [DataMember]
        public string AssigneeGroupId { get; set; }
        /// <summary>Query used to calculate task assignee group</summary>
        [DataMember]
        public string AssigneeGroupQuery { get; set; }
        /// <summary>True if task should be assigned to group, false - if it should be assigned to a person</summary>
        [DataMember]
        public bool IsGroupResponsible { get; set; }
        /// <summary>Information if task should be in 'enabled' status (execution not started yet) or 'executing' status</summary>
        [DataMember]
        public bool ExecutionStarted { get; set; }
        /// <summary>true if task assignee can give the task to another person, false if assignee cannot change person responsible</summary>
        [DataMember]
        public bool CanAssigneeDelegateTask { get; set; }
        /// <summary>in case of group tasks, if false - group members can take the task from group queue, if true - group manager has to assign tasks to group members</summary>
        [DataMember]
        public bool ManagerAssignsTask { get; set; }
        /// <summary>copy of task's data</summary>
        [DataMember]
        [JsonConverter(typeof(TaskDataJsonConverter))]
        public Dictionary<string, object> TaskData { get; set; }
        /// <summary>
        /// True if task can be taken from group queue by group members
        /// </summary>
        [DataMember]
        public bool CanTakeFromQueue { get; set; }
        /// <summary>
        /// True if the task can be completed without taking it from the group queue
        /// </summary>
        [DataMember]
        public bool CanCompleteOnGroup { get; set; }
        /// <summary>
        /// True if assignee can return the task to group queue
        /// </summary>
        [DataMember]
        public bool CanAssigneeReturnTaskToGroup { get; set; }
        /// <summary>
        /// True if assignee can assign the task to other members of the same group
        /// </summary>
        [DataMember]
        public bool CanAssigneeSendToOtherGroupMembers { get; set; }
        /// <summary>
        /// True if assignee can assign the task to other groups
        /// </summary>
        [DataMember]
        public bool CanAssigneeSendToOtherGroups { get; set; }
        /// <summary>
        /// True if start execution is explicit (you need to select the 'start execution' option, even if the task is assigned to you)
        /// </summary>
        [DataMember]
        public bool ExplicitStartExecution { get; set; }
        /// <summary>
        /// True if group leader can assign the task to group members
        /// </summary>
        [DataMember]
        public bool CanGroupLeaderAssignTask { get; set; }
        /// <summary>
        /// Name of auto-assignment algorithm (application-specific)
        /// </summary>
        [DataMember]
        public string AutoAssignmentStrategy { get; set; }
        /// <summary>
        /// Task completion deadline. Warn: nullables are badly treated by SOAP serializer.
        /// </summary>
        [DataMember]
        public DateTime? Deadline { get; set; }
        /// <summary>
        /// Estimated task start date. Warn: nullables are badly treated by SOAP serializer.
        /// </summary>
        [DataMember]
        public DateTime? PlannedStartDate { get; set; }
        /// <summary>
        /// Estimated task completion date. Warn: nullables are badly treated by SOAP serializer.
        /// </summary>
        [DataMember]
        public DateTime? PlannedEndDate { get; set; }

        /// <summary>
        /// External document ID - filled if process is associated
        /// with some external document.
        /// </summary>
        [DataMember]
        public string ExtDocumentId { get; set; }
        /// <summary>
        /// URL where task callbacks should
        /// be sent
        /// </summary>
        [DataMember]
        public string CallbackUrl { get; set; }

    }

    public class CreateWorkItemResponse : OperationResult
    {
        public string WorkItemId { get; set; }
    }
}
